
package com.hmsg.health.controller;

import com.hmsg.health.bean.vo.*;
import com.hmsg.health.dao.AppealDao;
import com.hmsg.health.dao.InviteDao;
import com.hmsg.health.dao.OrderDao;
import com.hmsg.health.dao.UserAccountDao;
import com.hmsg.health.dao.UserAccountRecordDao;
import com.hmsg.health.dao.UserDao;
import com.hmsg.health.service.MenWangSMSService;
import com.hmsg.health.service.UserService;
import com.hmsg.health.service.aes.SecurityData;

import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSBuilder;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyuncs.http.HttpResponse;
import com.hmsg.health.bean.Dto.PayResultDto;
import com.hmsg.health.bean.domain.BannerDo;
import com.hmsg.health.bean.domain.InviteDo;
import com.hmsg.health.bean.domain.SorderDo;
import com.hmsg.health.bean.domain.UserAccountDo;
import com.hmsg.health.bean.domain.UserAccountRecordDo;
import com.hmsg.health.bean.domain.UserDo;
import com.hmsg.health.bean.enums.StatusCode;
import com.hmsg.health.config.Constants;
import com.hmsg.health.config.PropertyConfig;
import com.hmsg.health.param.AccessToken;
import com.hmsg.health.param.ResponseResult;
import com.hmsg.health.security.IgnoreSecurity;
import com.hmsg.health.security.OpenApi;
import com.hmsg.health.security.TokenManager;
import com.hmsg.health.utils.ApiException;
import com.hmsg.health.utils.ErrorCode;
import com.hmsg.health.utils.GetScene;
import com.hmsg.health.utils.HttpInvoker;
import com.hmsg.health.utils.HttpResult;
import com.hmsg.health.utils.HttpUtil;
import com.hmsg.health.utils.IdWorker;
import com.hmsg.health.utils.RandomUtil;
import com.hmsg.health.utils.SignUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletResponse;

@Controller
@RequestMapping("/pay")
@Api(value = "ApplePayController", description = "苹果支付")
public class PayController {
	// 购买凭证验证地址
	private static final String verifyReceiptUrl = "https://buy.itunes.apple.com/verifyReceipt";
	// 测试的购买凭证验证地址
	private static final String verifyReceiptUrlSandbox = "https://sandbox.itunes.apple.com/verifyReceipt";

	private static int requestCounts = 0;
	@Autowired
	private UserAccountDao userAccountDao;
	@Autowired
	private UserAccountRecordDao userAccountRecordDao;
	static final IdWorker idWorker = new IdWorker(1);
	/**
	 * 重写X509TrustManager
	 */
	private static TrustManager myX509TrustManager = new X509TrustManager() {

		@Override
		public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
			// TODO Auto-generated method stub

		}

		@Override
		public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
			// TODO Auto-generated method stub

		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			// TODO Auto-generated method stub
			return null;
		}
	};

	@Autowired
	private OrderDao orderDao;

	/**
	 * 接收iOS端发过来的购买凭证
	 * 
	 * @param url
	 * @param strings
	 * @return
	 * @throws Exception
	 */
	@ApiOperation(value = "接收iOS端发过来的购买凭证", httpMethod = "POST", notes = "接收iOS端发过来的购买凭证")
	@PostMapping("/saveOrder")
	@ResponseBody
	@IgnoreSecurity
	@OpenApi
	@SecurityData
	private ResponseResult<PayResultDto> sendHttpsCoon(@RequestHeader(Constants.CLIENT_USER) Integer userId,
			@RequestBody @Validated PayVo vo) throws Exception {
		Integer goodsId = vo.getGoodsId();
		Map<String, String> map = new HashMap<String, String>();
		map.put("mchid", "1559175781");
		Integer price = 0;
		String goodsName = "商品名称";
		Integer count  =0;
		if(goodsId==3) {
			price = 600;
			count=6000;
			goodsName = "6000金币";
			map.put("total_fee", "" + 6);
		} else if(goodsId==2) {
			price = 1200;
			count=12000;
			goodsName = "12000金币";
			map.put("total_fee", "" + 12);
		} else if(goodsId==4) {
			price = 1800;
			count=18000;
			goodsName = "18000金币";
			map.put("total_fee", "" + 18);
		}else if(goodsId==5) {
			price = 2500;
			count=25000;
			goodsName = "25000金币";
			map.put("total_fee", "" + 2500);
		}else if(goodsId==6) {
			price = 3000;
			count=30000;
			goodsName = "30000金币";
			map.put("total_fee", "" + 3000);
		}else{
			price = 4000;
			count=40000;
			goodsName = "40000金币";
			map.put("total_fee", "" + 4000);
		}
		String otn = "SWJ" + idWorker.nextId();
		map.put("out_trade_no", otn);
		map.put("body", "金币购买");

		map.put("notify_url", "http://180.76.246.22:8071/shuawujing/pay/notify");// 请注意，，该路径需要payjs服务器可以直接访问，且结果为200。测试地址不行，www.baidu.com也不行
		String md5 = SignUtil.sign(map, "2mrXHs4D9iiWYyfd");
		map.put("sign", md5.toUpperCase());
		String result = HttpInvoker.readContentFromPost("https://payjs.cn/api/native", map);
		JSONObject jsonObject = new JSONObject(result);
		if (null != jsonObject && jsonObject.has("qrcode")) {

			SorderDo o = new SorderDo();
			o.setUserId(userId);

			o.setAmount(price);
			o.setGloadCount(count);
			o.setGoodsId(goodsId);
			o.setCreateTime(new Date());
			o.setStatus(0);
			o.setOrderNum(otn);
			try {
				orderDao.save(o);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			PayResultDto pr = new PayResultDto();
			pr.setOrderNum(otn);
			pr.setQrcode(jsonObject.getString("qrcode"));
			return new ResponseResult<PayResultDto>(StatusCode.SYSTEM_SUCCESS,pr );
		} else if (null != jsonObject && jsonObject.has("msg")) {
			return new ResponseResult<PayResultDto>(StatusCode.SYSTEM_ERROR, null);
		}
		return null;
	}
	
	/**
	 * 接收iOS端发过来的购买凭证
	 * 
	 * @param url
	 * @param strings
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/queryOrder")
	@ResponseBody
	@IgnoreSecurity
	@OpenApi
	@SecurityData
	private ResponseResult<Object> sendHttpsCoon(@RequestHeader(Constants.CLIENT_USER) Integer userId,
			String orderNum) throws Exception {
		
		
		SorderDo sd = new SorderDo();
		sd.setOrderNum(orderNum);
		List<SorderDo> list = orderDao.select(sd);
		if(list!=null&&list.size()>0){
			SorderDo res = list.get(0);
			if(res.getStatus()==1){
				return new ResponseResult<Object>(StatusCode.SYSTEM_SUCCESS,1);
			}else{
				return new ResponseResult<Object>(StatusCode.SYSTEM_SUCCESS,0);
			}
		}else {
			return new ResponseResult<Object>(StatusCode.SYSTEM_ERROR, null);
		}
	}
	
	
	
	@PostMapping(value = "/notify")
	@IgnoreSecurity
	@OpenApi
	@SecurityData
	@ResponseBody
    public ResponseResult<Object> payNotify(String return_code, String total_fee,
                                        String out_trade_no, String payjs_order_id, String transaction_id, String time_end,
                                        String openid, String mchid, String sign){
        System.out.println("-----------------PAYJS收到通知-------------------------------");
        
        SorderDo o = new SorderDo();
		o.setOrderNum(out_trade_no);
		List<SorderDo> list = orderDao.select(o);
		
		
		if(list!=null&&list.size()>0){
			o = list.get(0);
			o.setStatus(1);
			try {
				o.setPayTime(new Date());
				orderDao.update(o);
				
				UserAccountDo ua = userAccountDao.findUserAccount(o.getUserId());
				ua.setGlod(ua.getGlod()+o.getGloadCount());
				
				int res = userAccountDao.update(ua);
				if(res>0){
					UserAccountRecordDo uar = new UserAccountRecordDo();
					uar.setAmount(o.getGloadCount());
					uar.setGlodType(1);
					uar.setCreateTime(new Date());
					uar.setTitle("用户充值");
					uar.setUserId(o.getUserId());
					userAccountRecordDao.save(uar);
					return new ResponseResult<Object>(StatusCode.SYSTEM_SUCCESS, null);
				}else{
					return new ResponseResult<Object>(StatusCode.SYSTEM_ERROR, null);
				}
				
			} catch (Exception e) {
				e.printStackTrace();
				return new ResponseResult<Object>(StatusCode.SYSTEM_ERROR, null);
			}
		}else{
			
		}
        System.out.println("outOrderNumber:"+out_trade_no);
        System.out.println("return_code:"+return_code);
        System.out.println("total_fee:"+total_fee);
        System.out.println("out_trade_no:"+out_trade_no);
        System.out.println("payjs_order_id:"+payjs_order_id);
        System.out.println("transaction_id:"+transaction_id);
        System.out.println("time_end:"+time_end);
        System.out.println("openid:"+openid);
        System.out.println("mchid:"+mchid);
        System.out.println("sign:"+sign);
        return null;
    }
}
